package com.hnit.service;

import com.hnit.web.bean.ResponseResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "hello-service")   //服务名    -> 负载均衡
public interface HelloClient {
    //http://服务实例id:port/hello
    @GetMapping("/hello")  //映射地址
    ResponseResult getHello();
}

/**
 * 服务名：hello-service
 * 服务实例：2
 *  地址：2个
 *  List<Instance>
 *      169.254.43.53   8182
 *      172.20.10.4     8181
 *
 *      @FeignClient(name = "hello-service") -> 负载均衡器 -> 选择一台合适的实例(算法)  得到  ip:port
 *
 *      动态代理生成代理类：
 *      // 这是Feign基于HelloClient接口动态生成的代理类
 * public class HelloClientProxy implements HelloClient {
 *
 *     // 服务发现获取的实例列表
 *     private static final List<ServiceInstance> instances = Arrays.asList(
 *         new ServiceInstance("169.254.43.53", 8182),
 *         new ServiceInstance("172.20.10.4", 8181)
 *     );
 *
 *     // 负载均衡器
 *     private final LoadBalancer loadBalancer = new RandomLoadBalancer();
 *
 *     // HTTP客户端
 *     private final Client client = new feign.Client.Default(null, null);
 *
 *     @Override
 *     public String getHello() {
 *         // 1. 通过负载均衡器选择一个服务实例
 *         ServiceInstance instance = loadBalancer.choose(instances);
 *
 *         // 2. 构建请求URL（拼接服务实例地址和接口路径）
 *         String url = String.format("http://%s:%d/hello", instance.getHost(), instance.getPort());
 *
 *         // 3. 创建HTTP请求
 *         Request request = Request.create(
 *             Request.HttpMethod.GET,
 *             url,
 *             Request.Headers.empty(),
 *             null,
 *             null
 *         );
 *
 *         // 4. 执行请求
 *         try (Response response = client.execute(request, new Request.Options())) {
 *             if (response.status() == 200) {
 *                 return new String(response.body().asInputStream().readAllBytes());
 *             } else {
 *                 throw new RuntimeException("HTTP request failed with status: " + response.status());
 *             }
 *         } catch (IOException e) {
 *             throw new RuntimeException("IO error occurred during request execution", e);
 *         }
 *     }
 *
 *     // 服务实例类
 *     static class ServiceInstance {
 *         private final String host;
 *         private final int port;
 *
 *         public ServiceInstance(String host, int port) {
 *             this.host = host;
 *             this.port = port;
 *         }
 *
 *         public String getHost() {
 *             return host;
 *         }
 *
 *         public int getPort() {
 *             return port;
 *         }
 *     }
 *
 *     // 负载均衡器接口
 *     interface LoadBalancer {
 *         ServiceInstance choose(List<ServiceInstance> instances);
 *     }
 *
 *     // 随机负载均衡实现
 *     static class RandomLoadBalancer implements LoadBalancer {
 *         private final Random random = new Random();
 *
 *         @Override
 *         public ServiceInstance choose(List<ServiceInstance> instances) {
 *             return instances.get(random.nextInt(instances.size()));
 *         }
 *     }
 * }
 *
 * 关键部分解析
 * 服务实例列表：把服务发现得到的两个实例地址保存下来。
 * 负载均衡：采用随机算法从多个实例里挑选一个。
 * HTTP 请求构建：将服务实例的地址和接口路径组合成完整的 URL。
 * 请求执行：利用 Feign 内置的 HTTP 客户端发送请求，并且处理响应。
 *
 * 实际上，Feign 生成的代理类要比这个复杂得多，它还涵盖了编码器、解码器、拦截器等组件，这里只是展示了最核心的负载均衡和请求执行逻辑
 *
 */

